/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package bullets;

import java.util.LinkedList;

/**
 *
 * @author ajt019
 */
public class Board implements IBoard{
    
    public static int X_SIZE_DEFAULT = 10;
    public static int Y_SIZE_DEFAULT = 10;
    public static int MIN_ITEMS_NUMBER = 5;


    public Board(int ax, int ay){
        //m_fieldList = new LinkedList<Field>();
        
        m_x = ax; m_y = ay;
        m_board = new Field[m_x][m_y];
        
         for (int x = 0; x < m_x; ++x ){
            for (int y = 0; y < m_y; ++y ){ 
              m_board[x][y] = new Field(x, y, FieldType.TYPE_EMPTY);
            }
         }
        
        m_linesToCheck = new LinkedList<LinkedList<Field>>();
        
        
        // VERTICAL
        for (int x = 0; x < m_x; ++x ){
            LinkedList<Field> vLineToCheck = new LinkedList<Field>();
            for (int y = 0; y < m_y; ++y ){                
                vLineToCheck.add(m_board[x][y]);
            }
            if (vLineToCheck.size() >= MIN_ITEMS_NUMBER){
               m_linesToCheck.add(vLineToCheck);
           }
        }
        
        // HORIZONTAL
        for (int y = 0; y < m_y; ++y ){
            LinkedList<Field> hLineToCheck = new LinkedList<Field>();
            for (int x = 0; x < m_x; ++x ){                
                hLineToCheck.add(m_board[x][y]);
            }
            if (hLineToCheck.size() >= MIN_ITEMS_NUMBER){
               m_linesToCheck.add(hLineToCheck);
           }
        }
        
        // DIAGONAL DOWN (\)
        int total = (m_x-1) + (m_y-1);
        for(int i = 0; i <= total; ++i)
        {
           LinkedList<Field> diagonalLineToCheck = new LinkedList<Field>();
           for (int x = 0; x < m_x; ++x ){
               for (int y = 0; y < m_y; ++y ){
                   if(x+y == i){ // sum of X and Y in the same 'left' diagonal is unique and const
                       diagonalLineToCheck.add(m_board[x][y]);
                   }
               }
           }           
           if (diagonalLineToCheck.size() >= MIN_ITEMS_NUMBER){
               m_linesToCheck.add(diagonalLineToCheck);
           }             
        }
        
        // DIAGONAL UP (/)
        //for(int i = m_x-1; i >= (m_y-1); --i)
        for(int i = 0-(m_y-1); i <= (m_x-1); ++i)
        {
           LinkedList<Field> diagonalLineToCheck = new LinkedList<Field>();
           for (int x = 0; x < m_x; ++x ){
               for (int y = 0; y < m_y; ++y ){
                   if(x-y == i){ // diff of X and Y in the same 'right' diagonal is unique and const
                       diagonalLineToCheck.add(m_board[x][y]);
                   }
               }
           }           
           if (diagonalLineToCheck.size() >= MIN_ITEMS_NUMBER){
               m_linesToCheck.add(diagonalLineToCheck);
           }             
        }
        
    }
        
    public Board(){
        this(X_SIZE_DEFAULT, Y_SIZE_DEFAULT);        
    }    
    
    @Override
    public void markField(int x, int y, FieldType type)
    {
        if ( (x > m_x-1) || (y > m_y-1) || (null == m_board[x][y]) ) 
            //System.out.println("Discrepancy found (3)! " + Thread.currentThread().getStackTrace()[3].getMethodName() + ": " + Thread.currentThread().getStackTrace()[1].getLineNumber());
            LOGGER.LOG("Discrepancy found (3)!");
        else
            m_board[x][y].setType(type);
    }

        
    @Override
    public LinkedList< LinkedList<Field> > checkLines()
    {     
        /*
       System.out.println("checkLines - size: " + m_linesToCheck.size()); 
       for(List<Field> line : m_linesToCheck)
       {
           System.out.println(" - line size: " + line.size());
       }
        */
        
        
       LinkedList< LinkedList<Field> > result = new LinkedList<LinkedList<Field>>();
       
       for(LinkedList<Field> line : m_linesToCheck)
       {
           LinkedList<Field> bingo = new LinkedList<Field>();            
           FieldType lineType = FieldType.TYPE_EMPTY;
           for(Field field : line)
           {
               FieldType currentType = field.getType();
               if (lineType != currentType)
               {
                   if (bingo.size() >= MIN_ITEMS_NUMBER)
                   {
                       //System.out.println(" bingo1 " + bingo.size());
                       result.add(bingo);
                       bingo = new LinkedList<Field>(); // we may have more bingos in the same line
                   }
                   if (currentType != FieldType.TYPE_EMPTY)
                   {                 
                       //System.out.println(" adding2 " + field.getType() + " " + field.m_x + " " + field.m_y);
                       bingo.add(field);                       
                   }
                   
                    lineType = currentType;
                    //bingo.clear();
               }
               else if(currentType != FieldType.TYPE_EMPTY)
               {
                   //System.out.println(" adding " + field.getType() + " " + field.m_x + " " + field.m_y);

                   bingo.add(field);
               }
           }
           
            if (bingo.size() >= MIN_ITEMS_NUMBER)
            {
               // System.out.println(" bingo2 " + bingo.size());
                result.add(bingo);                
            }
       }

       return result;            
    }
    
    //private List<Field> m_fieldList;
    
    Field[][] m_board;
    LinkedList< LinkedList<Field> > m_linesToCheck;

    
    private int m_x;
    private int m_y;
}
